package com.google.memoryofaplace;

import java.util.Date;
import java.util.HashMap;
import java.util.Map.Entry;

import javax.jdo.PersistenceManager;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.SortDirection;
import com.google.appengine.repackaged.org.json.JSONArray;
import com.google.appengine.repackaged.org.json.JSONException;
import com.google.appengine.repackaged.org.json.JSONObject;
import com.google.memoryofaplace.model.TBPlaceComments;
import com.google.memoryofaplace.model.TBPlaceMedia;

public class BLDenounces {

	public static JSONObject denounce(long codPlace, long codDenouncedObject,
			int denounceObjectType, int denounceType) throws JSONException {
		JSONObject jResult = new JSONObject();

		try {
			if (Codes.DenounceObjectType.find(denounceObjectType) == null) {
				jResult = General.returnError(General
						.getLocaleMessage("invalidParams"));
			} else {

				Object objectDenounced = null;
				PersistenceManager pm = PMF.get().getPersistenceManager();
				Key parent = KeyFactory.createKey("TBPlaces", codPlace);
				Key child = null;
				if (denounceObjectType == Codes.DenounceObjectType.COMMENT
						.getCode()) {
					child = KeyFactory.createKey(parent, "TBPlaceComments",
							codDenouncedObject);
					objectDenounced = pm.getObjectById(TBPlaceComments.class,
							child);
				}
				if (denounceObjectType == Codes.DenounceObjectType.MEDIA
						.getCode()) {
					child = KeyFactory.createKey(parent, "TBPlaceMedia",
							codDenouncedObject);
					objectDenounced = pm.getObjectById(TBPlaceMedia.class,
							child);
				}

				pm.close();
				if (objectDenounced != null) {
					DatastoreService datastoreService = DatastoreServiceFactory
							.getDatastoreService();
					Long counter;
					Query qDenounce = new Query("TBDenounces");

					qDenounce.addFilter("codPlace", Query.FilterOperator.EQUAL,
							codPlace);
					qDenounce.addFilter("codDenouncedObject",
							Query.FilterOperator.EQUAL, codDenouncedObject);
					qDenounce.addFilter("denounceObjectType",
							Query.FilterOperator.EQUAL, denounceObjectType);
					qDenounce.addFilter("denounceType",
							Query.FilterOperator.EQUAL, denounceType);
					Entity denounce = datastoreService.prepare(qDenounce)
							.asSingleEntity();
					if (denounce != null) {
						counter = (Long) denounce.getProperty("counter");
						counter++;
						denounce.setProperty("counter", counter);

					} else {
						counter = Long.parseLong("1");
						denounce = new Entity("TBDenounces");
						denounce.setProperty("counter", counter);
						denounce.setProperty("codPlace", codPlace);
						denounce.setProperty("codDenouncedObject",
								codDenouncedObject);
						denounce.setProperty("denounceObjectType",
								denounceObjectType);
						denounce.setProperty("denounceType", denounceType);
						denounce.setProperty("creation", new Date());
					}
					datastoreService.put(denounce);
					jResult.put("status", General.OK);
					jResult.put("date", General.formatDate(new Date()));
					jResult.put("counter", counter);
					jResult.put("coddenounce", denounce.getKey().getId());
				} else {
					jResult = new JSONObject();
					jResult = General.returnError("object code "
							+ codDenouncedObject + " not found");
				}

			}
		} catch (Exception e) {
			jResult = new JSONObject();
			jResult = General.returnError(e.getMessage());
		}
		return jResult;
	}

	public static JSONObject getDenounces() throws JSONException {
		JSONObject jResult = new JSONObject();
		try {
			HashMap<String, Long> hm = new HashMap<String, Long>();
			Query q = new Query("TBDenounces");
			q.addSort("codDenouncedObject", SortDirection.ASCENDING);
			DatastoreService datastoreService = DatastoreServiceFactory
					.getDatastoreService();
			for (Entity result : datastoreService.prepare(q).asIterable()) {
				Long codDenouncedObject = (Long) result
						.getProperty("codDenouncedObject");
				Long denounceObjectType = (Long) result
						.getProperty("denounceObjectType");
				String codHash = codDenouncedObject + "|" + denounceObjectType;
				Long counter = (Long) result.getProperty("counter");
				if (!hm.containsKey(codHash)) {
					hm.put(codHash, counter);
				} else {
					counter += hm.get(codHash).longValue();
					hm.put(codHash, counter);
				}
			}
			HashMap<String, Long> sorted_hm = General.sortHashMapString(hm,
					false);
			JSONArray jDenounces = new JSONArray();
			for (Entry<String, Long> me : sorted_hm.entrySet()) {
				String codPlace = me.getKey();
				Long counter = me.getValue();
				String[] temp;
				temp = codPlace.split("\\|");
				JSONObject jDenounce = new JSONObject();
				jDenounce.put("coddenouncedobject", temp[0]);
				jDenounce.put("denounceobjecttype", temp[1]);
				jDenounce.put("counter", counter);
				jDenounces.put(jDenounce);
			}
			jResult.put("status", General.OK);
			jResult.put("date", General.formatDate(new Date()));
			jResult.put("results", jDenounces);
		} catch (Exception e) {
			jResult = new JSONObject();
			jResult = General.returnError(e.getMessage());
		}
		return jResult;
	}

	// TODO: no se utiliza
	public static JSONObject getDenouncesPlaces() throws JSONException {
		JSONObject jResult = new JSONObject();
		try {
			HashMap<Long, Long> hm = new HashMap<Long, Long>();
			Query q = new Query("TBDenounces");
			q.addSort("codPlace", SortDirection.ASCENDING);
			DatastoreService datastoreService = DatastoreServiceFactory
					.getDatastoreService();
			for (Entity result : datastoreService.prepare(q).asIterable()) {
				Long codPlace = (Long) result.getProperty("codPlace");
				Long counter = (Long) result.getProperty("counter");
				if (!hm.containsKey(codPlace)) {
					hm.put(codPlace, counter);
				} else {
					counter += hm.get(codPlace).longValue();
					hm.put(codPlace, counter);
				}
			}
			HashMap<Long, Long> sorted_hm = General.sortHashMap(hm, false);
			JSONArray jDenounces = new JSONArray();
			for (Entry<Long, Long> me : sorted_hm.entrySet()) {
				Long codPlace = me.getKey();
				Long counter = me.getValue();
				JSONObject jDenounce = new JSONObject();
				jDenounce.put("codplace", codPlace);
				jDenounce.put("counter", counter);
				jDenounces.put(jDenounce);
			}
			jResult.put("status", General.OK);
			jResult.put("date", General.formatDate(new Date()));
			jResult.put("results", jDenounces);
		} catch (Exception e) {
			jResult = new JSONObject();
			jResult = General.returnError(e.getMessage());
		}
		return jResult;
	}

}
